#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <qrcode.h>
#include <SPI.h>
#include "HX711.h"
#include "menu_logo.cpp"
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ESP8266HTTPClient.h>

// HX711 circuit wiring
const int LOADCELL_DOUT_PIN = 12;
const int LOADCELL_SCK_PIN = 13;
HX711 scale;
//配置屏幕
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for SSD1306 display connected using software SPI (default case):
const int OLED_MOSI = 0;  //d1
const int OLED_CLK =  16;  //d0
const int OLED_DC = 15;   
const int OLED_CS = 3;
const int OLED_RESET = 2;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,
  OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
QRcode qrcode (&display);

const char* ssid = "realme X2";
const char* password = "12345678";
const char* mqtt_server = "8.136.195.245";

WiFiClient espClient;
PubSubClient client(espClient);

long avg_maozhong = 118000;
char KEYPAD[8] = {'N','0','0','0','0','0','0','\0'};
int page = 0; //页面轮动，标记符
char now_page = 'm';//当前页面，标记符 
//m：首页，b：购买页，y：余额页，z：重量页，f：付款页，x：选择水果页
//e：支付内页，s：刷卡界面，c：充值界面，d：绑定界面,n:余额内页 ,:充值内页 .：绑卡内页
int fruit = 0;
long WEIGHT = 0; 
float PRICE = 0;
char* MONEYINCARD = NULL;
String PAYLOAD ="";
int HTTPSUCCESS = 404;
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE  (50)
char msg[MSG_BUFFER_SIZE];
int value = 0;

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
    PAYLOAD+=(char)payload[i];
  }
  Serial.println();
  
}


void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      // ... and resubscribe
      client.subscribe("fruit");
      
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

//----------------------------------下为setup---------------------------------------------------------------

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); // Initialize serial communications with the PC
  while (!Serial);    // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
  SPI.begin();        // Init SPI bus
  Wire.begin(5, 4); //初始化和arduino的通讯
  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
  
  // Clear the buffer
  display.clearDisplay();  
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 50);
  display.print("lt hmx");
  display.setCursor(10, 25);
  display.print("WIFI CONNECTING...");
  display.display();
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
  delay(1000);

  long maozhong[3] = {0,0,0};
  int i =0; 
  while(i<3){      
    if (scale.is_ready()){
      maozhong[i] = scale.read();
      Serial.println(maozhong[i]);
      i++;
    }
  }
  avg_maozhong = (maozhong[0]+maozhong[1]+maozhong[2])/3;
  Serial.print("平均毛重：");
  Serial.println(avg_maozhong);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  display.clearDisplay();
  display.setCursor(0, 50);
  display.print("lt hmx");
  display.setCursor(20, 25);
  display.print("WIFI CONNECTED!");
  display.display();
}

void loop() {
  int num = 0;
  // put your main code here, to run repeatedly:
  Wire.requestFrom(8, 8); //从8号slave获取8个字节
  while(Wire.available()){
    char c = Wire.read();
    if(c==NULL){//如果接收到的数据为空，则直接跳出接收
      break;
    }
    KEYPAD[num] = c;
    num++;
  }
  if(KEYPAD[0]=='N'){
    return;
  }
  Serial.print("KEYPAD DATA: ");Serial.println(KEYPAD);
  Serial.print("NOWPAGE DATA: ");Serial.println(now_page);

  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  
  //选择菜单
  SecondMenu();  
}

//----------------------------------------下为函数------------------------------------------
void Menu(){
   display.clearDisplay();
   if(page>=4){
      page = 0;
   }   
   if(page == 0){
      display.drawBitmap(0, 0, buy, 128, 64, WHITE);
      now_page = 'b';
      page++;      
   }   
   else if(page == 1){
      display.drawBitmap(0, 0, yue, 128, 64, WHITE);
      now_page = 'y';
      page++;      
   }
   else if(page == 2){
      display.drawBitmap(0, 0, chongzhi, 128, 64, WHITE);
      now_page = 'c';
      page++;      
   }
   else if(page == 3){
      display.drawBitmap(0, 0, bangding, 128, 64, WHITE);
      now_page = 'd';
      page++;      
   }   
   display.display();
}

void SecondMenu(){
  //二级菜单  选择水果界面
  if((now_page == 'b' && KEYPAD[0] == 'A') || now_page == 'x' || now_page =='z' || now_page == 'f' || now_page == 'e'){//如果当前位于首页且按下A 或者 当前位于选择水果页面 或者 当前位于称重界面 ！或者当前位于付款界面 都要进入这个循环
    //三级菜单 称重界面
    if(KEYPAD[0] == '1' || KEYPAD[0] == '2' || KEYPAD[0] == '3' || now_page =='z' || now_page == 'f' || now_page == 'e'){//如果选择了水果 或者 当前位于称重界面  ！或者 当前位于付款界面！则进入该称重循环
      //四级菜单 选择支付方式界面
      if(KEYPAD[0] == 'A' || now_page == 'f' || now_page == 'e'){
        //五级菜单 微信、刷卡支付界面
        String sc;
        if(KEYPAD[0] == '1' || KEYPAD[0] == '2' || now_page == 'e'){ 
          if(KEYPAD[0] == '1' && now_page != 'e'){//微信支付
            display.clearDisplay();
            qrcode.init();
            String s;
            if(fruit == 1){
              s="苹果+";
            }
            else if(fruit == 2){
              s="香蕉+";
            }
            else if(fruit == 3){
              s="桃子+";
            }
            s+=WEIGHT;
            s+='+';
            s+=(String)fruit;
            s+='+';
            s+=(String)PRICE;
            qrcode.create(s);
            display.setCursor(5,0);
            display.print(PRICE);
            display.print(" RMB");
            display.setCursor(90,0);
            display.print("#.Back");
            display.display();


          }
          if(KEYPAD[0] == '2' && now_page != 'e'){//卡片支付

            String s = "D"+(String)PRICE+"E";
            CardOperation(s);
            display.clearDisplay();
            display.setCursor(5,0);
            display.print(PRICE);
            display.print(" RMB");
            display.setCursor(90,0);
            display.print("#.Back");
            display.setCursor(40,30);
            display.print("Card HERE");
            display.display();
            
            Serial.println(fruit);
            if(fruit == 1){
              sc="{\"buyWay\":2,\"fruitName\":\"苹果\",\"fruitWeight\":"+(String)WEIGHT+",\"payWay\":1,\"totalPrice\":"+(String)PRICE+",\"unitPrice\":"+(String)fruit+",\"cardUid\":\"carduid602\"}";
            }
            else if(fruit == 2){
              sc="{\"buyWay\":2,\"fruitName\":\"香蕉\",\"fruitWeight\":"+(String)WEIGHT+",\"payWay\":1,\"totalPrice\":"+(String)PRICE+",\"unitPrice\":"+(String)fruit+",\"cardUid\":\"carduid602\"}";
            }
            else if(fruit == 3){
              sc="{\"buyWay\":2,\"fruitName\":\"桃子\",\"fruitWeight\":"+(String)WEIGHT+",\"payWay\":1,\"totalPrice\":"+(String)PRICE+",\"unitPrice\":"+(String)fruit+",\"cardUid\":\"carduid602\"}";
            }
            Serial.println(sc);
            if(HTTPSUCCESS != 200){
              HTTPClient httpClient;
              httpClient.begin("http://8.136.195.245:8000/orders/payOrder");
              httpClient.addHeader("Content-Type", "application/json");
              int httpCode = httpClient.POST(sc);
              if(httpCode == 200){
                Serial.println("Success!");
                HTTPSUCCESS = 200;
              }
              else{
                Serial.println(httpCode);
              }
              httpClient.end();            
            }
            
          }
          if(PAYLOAD == "200"){
            now_page = 'b';
            PAYLOAD = "";
            KEYPAD[0] = 'N';
            MONEYINCARD =NULL;
            display.clearDisplay();
            display.setCursor(25,30);
            display.print("Success!");
            display.display();
            delay(1000);
            Menu();
            return;
          }
          else if(PAYLOAD == "400" || PAYLOAD == "401"){
            now_page = 'b';
            PAYLOAD = "";
            KEYPAD[0] = 'N';
            MONEYINCARD =NULL;
            display.clearDisplay();
            display.setCursor(25,30);
            display.print("Failed!");
            display.display();
            delay(1000);
            Menu();
            return;
          }
         
          if(KEYPAD[0] == 'Y'){//KEYPAD第一位为Y，意味着arduino将余额传输过来了，后6位即为余额
            MONEYINCARD = &KEYPAD[1];
            KEYPAD[0]='N';   
          } 
          if(MONEYINCARD != NULL){
            display.clearDisplay();
            display.setCursor(20,20);
            display.print("Card has Money:");
            display.setCursor(30,35);
            display.print(MONEYINCARD);
            display.print(" RMB");
            display.setCursor(80,55);
            display.print("#.Back");
            display.display();
            if(KEYPAD[0] == '#'){
              now_page = 'b';
              KEYPAD[0] = 'N';
              MONEYINCARD = NULL;
              HTTPSUCCESS = 404;
              Menu();
            }
            return;
          }          
          now_page = 'e'; 
          if(KEYPAD[0] == '#'){
            now_page = 'b';
            PAYLOAD = "";
            KEYPAD[0] = 'N';
            MONEYINCARD = NULL;
            Menu();
          }      
          return;
        }

        float price = (WEIGHT/100.0) * fruit;
        PRICE = price;
        display.clearDisplay();
        display.setTextSize(2);
        display.setCursor(5,0);
        display.print(price);
        display.print(" RMB");
        display.setTextSize(1);
        display.setCursor(5,30);
        display.print("1.WeChat Pay");
        display.setCursor(5,40);
        display.print("2.Card Pay");
        display.setTextSize(1);
        display.setCursor(80,55);
        display.print("#.Back");
        display.display();

        now_page = 'f';
        if(KEYPAD[0] == '#'){
          now_page = 'b';
          PAYLOAD = "";
          KEYPAD[0] = 'N';
          MONEYINCARD = NULL;
          Menu();
        }
        return;
      }
      if(now_page == 'x'){
        fruit = KEYPAD[0]-'0';
        Serial.print("fruit: ");Serial.println(fruit);
      }
      now_page = 'z';
    
      display.clearDisplay();
      if (scale.is_ready()) {
        long reading = scale.read();
        Serial.println(reading);
        long weight =(reading-avg_maozhong)/429.5;
        WEIGHT = weight;
        if(weight>=0){
          display.clearDisplay();
          display.setCursor(50,30);
          display.print(weight);
          display.print(" g");
          display.setCursor(5,55);
          display.print("A.Yes");
          display.setCursor(80,55);
          display.print("#.Back");
          display.display();
        }
        else{
          display.clearDisplay();
          display.setCursor(50,30);
          display.print(0);
          display.print(" g");
          display.setCursor(5,55);
          display.print("A.Yes");
          display.setCursor(80,55);
          display.print("#.Back");
          display.display();
        }
      } 
      else {
        Serial.println("HX711 not found.");
      }
      if(KEYPAD[0] == '#'){
        now_page = 'b';
        PAYLOAD = "";
        KEYPAD[0] = 'N';
        MONEYINCARD = NULL;
        Menu();
      }
      return;
    }
    display.clearDisplay();
    display.setTextSize(2);
    display.setCursor(5,0);
    display.print("1.Apple");
    display.setCursor(5,20);
    display.print("2.Banana");
    display.setCursor(5,40);
    display.print("3.Peach");
    display.setTextSize(1);
    display.setCursor(80,55);
    display.print("#.Back");
    display.display();
    now_page = 'x';
    page = 0;  
     //按#返回上级界面  
    if(KEYPAD[0] == '#'){
      now_page = 'b';
      KEYPAD[0] = 'N';
      Menu();
    }
   
    return;
  }

  //二级菜单 查询余额内页
  if((now_page == 'y' && KEYPAD[0] == 'A') || now_page == 'n' ||(now_page == 'n' && KEYPAD[0] == '#')){
    display.clearDisplay();
    if(KEYPAD[0] == 'Y'){//KEYPAD第一位为Y，意味着arduino将余额传输过来了，后6位即为余额
      MONEYINCARD = &KEYPAD[1];
      KEYPAD[0]='N';   
    }
      
    if(MONEYINCARD != NULL){
      display.setCursor(20,20);
      display.print("Card has Money:");
      display.setCursor(30,35);
      display.print(MONEYINCARD);
      display.print(" RMB");
      display.setCursor(80,55);
      display.print("#.Back");
      display.display();
      if(KEYPAD[0] == '#'){
        page--;
        PAYLOAD = "";
        KEYPAD[0] = 'N';
        MONEYINCARD = NULL;
        Menu();
      }
      return;
    }
    display.setTextSize(1);
    display.setCursor(15,20);
    display.print("Put Card On RFID");
    display.setTextSize(1);
    display.setCursor(80,55);
    display.print("#.Back");
    display.display();
    CardOperation("Y");
    now_page = 'n';
    if(KEYPAD[0] == '#'){
      page--;
      PAYLOAD = "";
      KEYPAD[0] = 'N';
      MONEYINCARD = NULL;
      Menu();
    }
    return;
  }

  //二级菜单 选择充值金额页
  if((now_page == 'c' && KEYPAD[0] == 'A') || now_page == ',' || now_page ==';' ||(now_page == ',' && KEYPAD[0] == '#')){
    //三级菜单 放卡充值
    if(KEYPAD[0] == '1' || KEYPAD[0] == '2' || KEYPAD[0] == '3' ||now_page ==';'){
      if(now_page == ','){
        fruit = (KEYPAD[0]-'0')*10;
        Serial.print("RECHARGE: ");Serial.println(fruit);
      }
      String s = "A"+(String)fruit+"E";
      now_page = ';';
      if(now_page == ';'){
        if(MONEYINCARD != NULL){
          if(PAYLOAD == "200"){
            CardOperation(s);    
            MONEYINCARD = NULL;
            if(KEYPAD[0] == 'Y'){//KEYPAD第一位为Y，意味着arduino将余额传输过来了，后6位即为余额
              MONEYINCARD = &KEYPAD[1];
              KEYPAD[0]='N';   
            } 
            if(MONEYINCARD != NULL){
              display.clearDisplay();
              display.setCursor(20,20);
              display.print("Card has Money:");
              display.setCursor(30,35);
              display.print(MONEYINCARD);
              display.print(" RMB");
              display.setCursor(80,55);
              display.print("#.Back");
              display.display();
              if(KEYPAD[0] == '#'){
                page--;
                PAYLOAD = "";
                KEYPAD[0] = 'N';
                MONEYINCARD = NULL;
                Menu();
              }
              return;
            }   
            return;
          }else if(PAYLOAD == "400" || PAYLOAD == "401"){
            page--;
            PAYLOAD = "";
            KEYPAD[0] = 'N';
            MONEYINCARD = NULL;
            display.clearDisplay();
            display.setCursor(25,30);
            display.print("Failed!");
            display.display();
            delay(1000);
            Menu();
            return;
          }
          display.clearDisplay();
          qrcode.init();
          String cz = "carduid"+ (String)MONEYINCARD[0]+ (String)MONEYINCARD[1]+ (String)MONEYINCARD[2] +'+'+(String)fruit;
          Serial.println(cz);
          qrcode.create(cz);
          
          display.setCursor(90,0);
          display.print("#.Back");
          display.display();

          if(KEYPAD[0] == '#'){
              page--;
              PAYLOAD = "";
              KEYPAD[0] = 'N';
              MONEYINCARD = NULL;
              Menu();
          }
          return;
        }
        CardOperation("B");
        display.clearDisplay();
        display.setTextSize(1);
        display.setCursor(15,20);
        display.print("Put Card On RFID");
        display.setCursor(20,30);
        display.print("Till Success!!");        
        display.setTextSize(1);
        display.setCursor(80,55);
        display.print("#.Back");
        display.display();
        if(KEYPAD[0] == 'Y'){//KEYPAD第一位为Y，意味着arduino将余额传输过来了，后6位即为余额
              MONEYINCARD = &KEYPAD[1];
              KEYPAD[0]='N';   
        } 
        if(KEYPAD[0] == '#'){
          page--;
          PAYLOAD = "";
          KEYPAD[0] = 'N';
          MONEYINCARD = NULL;
          Menu();
        }
              

        return;
      }
      
       
  
    }
    display.clearDisplay();
    display.setTextSize(1);
    display.setCursor(0,0);
    display.print("Amount Of Recharge:");
    display.setCursor(5,20);
    display.print("1.10");
    display.setCursor(5,30);
    display.print("2.20");
    display.setCursor(5,40);
    display.print("3.30");
    display.setTextSize(1);
    display.setCursor(80,55);
    display.print("#.Back");
    display.display();
    now_page = ',';
    if(KEYPAD[0] == '#'){
        page--;
        PAYLOAD = "";
        KEYPAD[0] = 'N';
        MONEYINCARD = NULL;
        Menu();
    }
    return;
  }
  
  //二级菜单 绑卡内页
  if((now_page == 'd' && KEYPAD[0] == 'A') || now_page == '.' ||(now_page == 'n' && KEYPAD[0] == '#')){
    
    if(now_page != '.'){
      CardOperation("B");
      display.clearDisplay();
      display.setTextSize(1);
      display.setCursor(15,20);
      display.print("Put Card On RFID");
      display.setCursor(20,30);
      display.print("And Open APP!");
      display.setCursor(80,55);
      display.print("#.Back");
      display.display();
      now_page = '.';
    }

    if(PAYLOAD == "200"){
      page--;
      PAYLOAD = "";
      KEYPAD[0] = 'N';
      MONEYINCARD = NULL;
      display.clearDisplay();
      display.setCursor(25,30);
      display.print("Success!");
      display.display();
      delay(1000);
      Menu();
      return;
    }
    else if(PAYLOAD == "400" || PAYLOAD == "401"){
       page--;
      PAYLOAD = "";
      KEYPAD[0] = 'N';
      MONEYINCARD = NULL;
      display.clearDisplay();
      display.setCursor(25,30);
      display.print("Failed!");
      display.display();
      delay(1000);
      Menu();
      return;
    }
    if(KEYPAD[0] == 'Y'){//KEYPAD第一位为Y，意味着arduino将uid传输过来了
        MONEYINCARD = &KEYPAD[1];
        KEYPAD[0]='N';   
    } 
    if(MONEYINCARD != NULL){
      display.clearDisplay();
      qrcode.init();
      String uid = "carduid"+ (String)MONEYINCARD[0]+ (String)MONEYINCARD[1]+ (String)MONEYINCARD[2];
      Serial.println(uid);
      qrcode.create(uid);
      
      display.setCursor(90,0);
      display.print("#.Back");
      display.display();
      if(KEYPAD[0] == '#'){
          page--;
          PAYLOAD = "";
          KEYPAD[0] = 'N';
          MONEYINCARD = NULL;
          Menu();
      }
      return;
    }

    
    if(KEYPAD[0] == '#'){
        page--;
        PAYLOAD = "";
        KEYPAD[0] = 'N';
        MONEYINCARD = NULL;
        Menu();
    }
    return;
  } 

  //选择一级菜单
  if((now_page == 'm' && KEYPAD[0] != 'N' &&KEYPAD[0] != ' ')|| KEYPAD[0] == '#'){
    Menu();
    KEYPAD[0] = 'N';
  }
}
//money：增减的钱数,格式 (A/D)+钱数+E ，A表示增加，D表示减少，E结尾标识符
void CardOperation(String code){
  Serial.print("CARD CODE: ");Serial.println(code);
  const char *c = code.c_str();
  Wire.beginTransmission(8); /* begin with device address 8 */
  Wire.write(c);  /* sends hello string */
  Wire.endTransmission();    /* stop transmitting */
}
